package twitter

//
// import (
//	"crypto/tls"
//	"encoding/json"
//	"fmt"
//	"github.com/go-resty/resty/v2"
//	"github.com/google/uuid"
//	"github.com/panjf2000/ants/v2"
//	"sieve_engine/lib/config"
//	"sieve_engine/lib/log"
//	"net/http"
//	"net/url"
//	"os"
//	"sieve_engine/execute"
//	"sieve_engine/task"
//	"sieve_engine/utils"
//	"strconv"
//	"strings"
//	"sync"
//	"time"
// )
//
// type twitterExecutor struct {
//	*execute.DefaultExecutor
//	execute.DefaultNetWorkConfig
// }
//
// var (
//	twExecutor execute.TaskExecutorInterface = &twitterExecutor{
//		DefaultExecutor: &execute.DefaultExecutor{
//			Debug:                *config.Bool("sieve.twitter.debug", true, "debug"),
//			PrintMore:            *config.Bool("sieve.twitter.print_more", true, "print more"),
//			ProxyEnable:          *config.Bool("sieve.twitter.proxy.enable", true, "proxy enable"),
//			ProxyDebug:           *config.Bool("sieve.twitter.proxy.debug", true, "proxy debug"),
//			NetworkErrRetryCount: *config.Int("sieve.twitter.proxy.retry_count_if_network_error", -1, "retry count if network error"),
//			DefaultResultCache:   execute.NewDefaultResultCache(),
//		},
//	}
//	poolOnce   = sync.Once{}
//	antPools   *ants.PoolWithFunc
//	notifyChan = make(chan struct{}, 32)
//	tokenList  = NewMessageQueue()
//	//fetchingToken = syncx.ForAtomicBool(false)
// )
//
// const (
//	twitterOauth2Token  = "https://api.twitter.com/oauth2/token"
//	twitterGuestToken   = "https://api.twitter.com/1.1/guest/activate.json"
//	twitterFlowTokenUrl = "https://api.twitter.com/1.1/onboarding/task.json?flow_name=login&api_version=1&known_device_token=&sim_country_code=us"
// )
//
// func init() {
//	execute.Register("twitter", twExecutor)
// }
//
// var (
//	delChannel     = make(chan []string, 256)
//	tokenCacheOnce = sync.Once{}
//	tokenCache     = struct {
//		cache  map[string]*TokenData
//		locker sync.Mutex
//	}{
//		cache: make(map[string]*TokenData),
//	}
// )
//
// func getTokenCacheSize() int {
//	tokenCache.locker.Lock()
//	defer tokenCache.locker.Unlock()
//
//	return len(tokenCache.cache)
// }
//
// func tryLock() bool {
//
//	var (
//		fetchCount = 3
//		b          bool
//	)
//	for fetchCount > 0 {
//		b = tokenCache.locker.TryLock()
//		if !b {
//			time.Sleep(time.Millisecond * 2)
//			fetchCount = fetchCount - 1
//			continue
//		} else {
//			break
//		}
//	}
//
//	if !b {
//		return false
//	}
//
//	return true
// }
//
// func getTokenCache() *TokenData {
//
//	tokenCacheOnce.Do(func() {
//		go func() {
//			for v := range delChannel {
//
//				for _, vv := range v {
//					if tryLock() {
//						if len(v) == len(tokenCache.cache) {
//							tokenCache.cache = make(map[string]*TokenData)
//							tokenCache.locker.Unlock()
//							break
//						}
//						delete(tokenCache.cache, vv)
//						tokenCache.locker.Unlock()
//					}
//				}
//			}
//		}()
//	})
//
//	if !tryLock() {
//		return nil
//	}
//
//	defer tokenCache.locker.Unlock()
//
//	var r *TokenData
//	if len(tokenCache.cache) == 0 {
//		return nil
//	}
//
//	var (
//		now            = time.Now()
//		deleteElements []string
//	)
//
//	for _, v := range tokenCache.cache {
//
//		/* token 已经失效 */
//		if (v.XRateLimitReset > 0 && v.XRateLimitLimit > 0 && (now.Unix() > int64(v.XRateLimitReset) || v.XRateLimitRemaining <= 0)) || v.IsTokenInvalid.True() {
//			deleteElements = append(deleteElements, v.XClientUUID)
//		} else {
//			if !v.IsRefreshToken.True() {
//				if v.IsBadGuestToken.True() || v.IsExpiredFlowToken.True() {
//					v.IsRefreshToken.Set(true)
//					tokenCache.cache[v.XClientUUID] = v
//				}
//				r = v
//				break
//			}
//		}
//	}
//
//	if len(deleteElements) > 0 {
//		select {
//		case delChannel <- deleteElements:
//			break
//		default:
//			break
//		}
//	}
//	return r
// }
//
// func setOrUpdateTokenCache(token *TokenData) {
//
//	tokenCache.locker.Lock()
//	defer tokenCache.locker.Unlock()
//
//	//tokenCache.cache[token.Authorization] = token
//	tokenCache.cache[token.XClientUUID] = token
// }
//
// func (s *twitterExecutor) Execute(params execute.TaskExecutorParams, taskProgress *task.Result) error {
//
//	return s.DefaultExecutor.Execute(params, taskProgress, s.getApi)
// }
//
// func (s *twitterExecutor) getNetWorkConfig() *execute.NetWorkConfig {
//
//	def := execute.GetSycTransportSetting()
//	def.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
//	def.IdleConnTimeout = time.Second * 90
//	def.ExpectContinueTimeout = time.Second * 10
//	def.DisableKeepAlives = false
//
//	return &execute.NetWorkConfig{
//		TransPortConfig: def,
//		HttpConfig: execute.HttpConfig{
//			Timeout: time.Second * 60,
//		},
//	}
// }
//
// func (s *twitterExecutor) getApi(phone string, params execute.TaskExecutorParams,
//	roundTripper http.RoundTripper, reuseProxy bool) (http.RoundTripper, bool, *url.URL, error) {
//
//	var (
//		attAndFlowToken = AttAndFlowTokenResp{}
//		retryCount      = s.NetworkErrRetryCount // 失败这个多次就设置为失败(筛以有效设置为invalid?) -1 表示一直重试
//		step3RetryCount = retryCount
//		tokenFromCache  bool
//		poolOption      = []ants.Option{
//			ants.WithExpiryDuration(time.Duration(1800) * time.Second), // 30分钟
//			ants.WithPreAlloc(true),
//			ants.WithPanicHandler(func(err interface{}) {
//				log.Err(fmt.Sprintf("执行任务崩溃:%+v", utils.Stack()))
//				_, _ = fmt.Fprintln(os.Stderr, err)
//			}),
//		}
//		poolCallBack = func(i interface{}) {
//			for range notifyChan {
//				var (
//					twitterTokenResp = TokenResp{}
//					tokenData        = NewTwitterTokenData()
//					guestToken       = GuestTokenResp{}
//					_retryCount      = -1
//					step1RetryCount  = _retryCount
//					step2RetryCount  = _retryCount
//					_reuseProxy      = false
//				)
//				for i := 0; i < step1RetryCount || step1RetryCount == -1; i++ {
//
//					if _, _, pUrl, err := s.step1(params, roundTripper, _reuseProxy, &twitterTokenResp); err != nil {
//
//						_reuseProxy = false
//						sleepDuration := time.Millisecond * 3
//						if s.PrintMore {
//							log.Err(fmt.Sprintf("当前(任务编号:%v,批次号:%v ,号码:%v),使用代理:(%v) ,执行任务(第%v次 )失败:%v ,获取的token信息(缓存获取:%v %v),休息%v后继续执行",
//								params.TaskInfo.Id, params.BatchIndex, phone, pUrl, i+1, err, tokenFromCache, tokenData.ToString(), sleepDuration))
//						}
//						//if i == step2RetryCount-1 {
//						//	return rt, b, pUrl, err
//						//}
//						time.Sleep(sleepDuration)
//						continue
//					} else {
//						tokenData.Cookie = twitterTokenResp.CookieString
//						auth := fmt.Sprintf("%v %s", twitterTokenResp.TokenType, twitterTokenResp.AccessToken)
//						tokenData.Authorization = auth
//						setOrUpdateTokenCache(tokenData)
//						break
//					}
//				}
//
//				reuseProxy = false
//				for i := 0; i < step2RetryCount || step2RetryCount == -1; i++ {
//
//					if _, _, pUrl, err := s.step2(params, roundTripper, reuseProxy, tokenData, &guestToken); err != nil {
//
//						reuseProxy = false
//						sleepDuration := time.Millisecond * 3
//						if s.PrintMore {
//							log.Err(fmt.Sprintf("当前(任务编号:%v,批次号:%v ,号码:%v),使用代理:(%v) ,执行任务(第%v次 )失败:%v ,获取的token信息(缓存获取:%v %v),休息%v后继续执行",
//								params.TaskInfo.Id, params.BatchIndex, phone, pUrl, i+1, err, tokenFromCache, tokenData.ToString(), sleepDuration))
//						}
//
//						//if i == step2RetryCount-1 {
//						//	return rt, b, pUrl, err
//						//}
//
//						time.Sleep(sleepDuration)
//						continue
//					} else {
//						tokenData.IsTokenInvalid.Set(false)
//						tokenData.IsBadGuestToken.Set(false)
//						tokenData.IsRefreshToken.Set(false)
//						tokenData.XGuestToken = guestToken.GuestToken
//						tokenList.Push(tokenData)
//						//setOrUpdateTokenCache(tokenData)
//						break
//					}
//				}
//			}
//		}
//	)
//
//	poolOnce.Do(func() {
//		antPools, _ = ants.NewPoolWithFunc(50000, poolCallBack, poolOption...)
//	})
//
//	var (
//		tokenData   *TokenData
//		fCheckValid = func(ele interface{}, size int) bool {
//
//			var (
//				v   = ele.(*TokenData)
//				now = time.Now()
//			)
//			if (v.XRateLimitReset > 0 && v.XRateLimitLimit > 0 && (now.Unix() > int64(v.XRateLimitReset) || v.XRateLimitRemaining <= 0)) || v.IsTokenInvalid.True() {
//				return false
//			}
//			return true
//		}
//	)
//
//	for tokenData == nil {
//
//		ele, _, _ := tokenList.PopWithCallBack(fCheckValid)
//		if ele == nil {
//			/* 每次都写入一次通知事件 */
//			select {
//			case notifyChan <- struct{}{}:
//				break
//			default:
//				break
//			}
//			time.Sleep(time.Millisecond * 5)
//			continue
//		}
//
//		tokenData = ele.(*TokenData)
//	}
//
//	if t := getTokenCache(); t != nil {
//		tokenFromCache = true
//		tokenData = t
//	} else {
//		tokenData.IsRefreshToken.Set(true)
//	}
//
//	if s.PrintMore {
//		log.Info(fmt.Sprintf("缓存的 token 数量有:%v", getTokenCacheSize()))
//	}
//
//	reuseProxy = false
//	for i := 0; i < step3RetryCount || step3RetryCount == -1; i++ {
//
//		if rt, b, pUrl, err := s.step3(params, roundTripper, reuseProxy, tokenData, &attAndFlowToken); err != nil {
//			reuseProxy = false
//			sleepDuration := time.Millisecond * 3
//			if s.PrintMore {
//				log.Err(fmt.Sprintf("当前(任务编号:%v,批次号:%v ,号码:%v),使用代理:(%v) ,执行任务(第%v次 )失败:%v ,获取的token信息(缓存获取:%v %v),休息%v后继续执行",
//					params.TaskInfo.Id, params.BatchIndex, phone, pUrl, i+1, err, tokenFromCache, tokenData.ToString(), sleepDuration))
//			}
//
//			if i == step3RetryCount-1 {
//				return rt, b, pUrl, err
//			}
//
//			time.Sleep(sleepDuration)
//			continue
//		} else {
//			tokenData.IsTokenInvalid.Set(false)
//			tokenData.IsExpiredFlowToken.Set(false)
//			break
//		}
//	}
//
//	defer func() {
//		tokenData.IsTokenInvalid.Set(false)
//		tokenData.IsBadGuestToken.Set(false)
//		tokenData.IsExpiredFlowToken.Set(false)
//	}()
//
//	if s.PrintMore {
//		log.Info(fmt.Sprintf("当前(任务编号:%v,批次号:%v,号码:%v),获取的token信息(缓存获取:%v %v)",
//			params.TaskInfo.Id, params.BatchIndex, phone, tokenFromCache, tokenData.ToString()))
//	}
//
//	reuseProxy = false
//	return s.step4(phone, params, roundTripper, reuseProxy, tokenData, &attAndFlowToken)
// }
//
// func (s *twitterExecutor) step1(params execute.TaskExecutorParams, roundTripper http.RoundTripper,
//	reuseProxy bool, twitterTokenResp *TokenResp) (http.RoundTripper, bool, *url.URL, error) {
//
//	var (
//		client   = resty.New()
//		proxyURL *url.URL
//	)
//	if !reuseProxy {
//		/* 如果不带用代理复用策略，那么就重新获取代理 */
//		roundTripper, proxyURL = execute.SetDefaultTransport("", s.getNetWorkConfig())
//	}
//
//	client.SetTransport(roundTripper).SetTimeout(s.getNetWorkConfig().HttpConfig.Timeout)
//	step1AddHeader(client.Header, map[string][]string{
//		"X-Client-UUID":             {utils.RandomString(16)},
//		"X-Twitter-Client-DeviceID": {uuid.NewString()},
//		"Authorization":             {"Basic M25WdVNvQlpueDZVNHZ6VXhmNXc6QmNzNTlFRmJic2RGNlNsOU5nNzFzbWdTdFdFR3dYWEtTall2UFZ0N3F5cw=="},
//		"Content-Type":              {"application/x-www-form-urlencoded"},
//		"X-B3-TraceId":              {utils.RandomString(16)},
//	})
//	resp, err := client.SetDebug(s.ProxyDebug).R().SetBody("grant_type=client_credentials").
//		Post(fmt.Sprintf("%v", twitterOauth2Token))
//	if err != nil {
//		if s.Debug {
//			log.Err(fmt.Sprintf("任务ID:%v 任务批次:%v 请求接口错误:%v", params.TaskInfo.Id, params.BatchIndex, err))
//		}
//
//		return roundTripper, false, proxyURL, err
//	}
//
//	err = json.Unmarshal(resp.Body(), twitterTokenResp)
//	if err != nil {
//		return roundTripper, false, proxyURL, err
//	}
//
//	var cookieString string
//	for _, c := range resp.RawResponse.Header.Values("Set-Cookie") {
//		length := strings.Index(c, ";")
//		subCookie := c[0:length]
//		cookieString = cookieString + subCookie + ";"
//	}
//	twitterTokenResp.CookieString = cookieString
//
//	return roundTripper, true, proxyURL, nil
// }
//
// func (s *twitterExecutor) step2(params execute.TaskExecutorParams, roundTripper http.RoundTripper,
//	reuseProxy bool, twitterTokenResp *TokenData, guestToken *GuestTokenResp) (http.RoundTripper, bool, *url.URL, error) {
//
//	var (
//		client   = resty.New()
//		proxyURL *url.URL
//	)
//	if !reuseProxy {
//		/* 如果不带用代理复用策略，那么就重新获取代理 */
//		roundTripper, proxyURL = execute.SetDefaultTransport("", s.getNetWorkConfig())
//	}
//
//	client.SetTransport(roundTripper).SetTimeout(s.getNetWorkConfig().HttpConfig.Timeout)
//	step2AddHeader(client.Header, map[string][]string{
//		"X-Twitter-Client-AdID":              {twitterTokenResp.XTwitterClientAdID},
//		"X-Client-UUID":                      {twitterTokenResp.XClientUUID},
//		"X-Twitter-Client-DeviceID":          {twitterTokenResp.XTwitterClientDeviceID},
//		"Authorization":                      {twitterTokenResp.Authorization},
//		"X-B3-TraceId":                       {utils.RandomString(16)},
//		"Cookie":                             {twitterTokenResp.Cookie},
//		"X-Twitter-Client-Limit-Ad-Tracking": {"0"},
//	})
//	resp, err := client.SetDebug(s.ProxyDebug).R().
//		Post(fmt.Sprintf("%v", twitterGuestToken))
//	if err != nil {
//		if s.PrintMore {
//			log.Err(fmt.Sprintf("任务ID:%v 任务批次:%v 请求接口错误:%v", params.TaskInfo.Id, params.BatchIndex, err))
//		}
//		s.dealTokenInvalid(err, twitterTokenResp)
//		return roundTripper, false, proxyURL, err
//	}
//
//	err = json.Unmarshal(resp.Body(), guestToken)
//	if err != nil {
//		return roundTripper, false, proxyURL, err
//	}
//
//	return roundTripper, false, proxyURL, nil
// }
//
// func (s *twitterExecutor) step3(params execute.TaskExecutorParams, roundTripper http.RoundTripper,
//	reuseProxy bool, tokenData *TokenData, attAndFlowToken *AttAndFlowTokenResp) (http.RoundTripper, bool, *url.URL, error) {
//
//	var (
//		client   = resty.New()
//		proxyURL *url.URL
//	)
//	if !reuseProxy {
//		/* 如果不带用代理复用策略，那么就重新获取代理 */
//		roundTripper, proxyURL = execute.SetDefaultTransport("", s.getNetWorkConfig())
//	}
//
//	numberFlowToken := FlowTokenInfo
//	numberFlowTokenData, _ := json.Marshal(numberFlowToken)
//	client.SetTransport(roundTripper).SetTimeout(s.getNetWorkConfig().HttpConfig.Timeout)
//	step3AddHeader(client.Header, map[string][]string{
//		"Content-Type":                       {"application/json"},
//		"Cookie":                             {tokenData.Cookie},
//		"OS-Version":                         {"29"},
//		"Authorization":                      {tokenData.Authorization},
//		"System-User-Agent":                  {"Dalvik/2.1.0 (Linux; U; Android 10; Pixel 3 Build/QQ3A.200805.001)"},
//		"Twitter-Display-Size":               {"1080x2028x440"},
//		"X-Guest-Token":                      {tokenData.XGuestToken},
//		"X-B3-TraceId":                       {utils.RandomString(16)},
//		"X-Client-UUID":                      {tokenData.XClientUUID},
//		"X-Twitter-Client-AdID":              {tokenData.XTwitterClientAdID},
//		"X-Twitter-Client-AppSetID":          {tokenData.XTwitterClientAppSetID},
//		"X-Twitter-Client-DeviceID":          {tokenData.XTwitterClientDeviceID},
//		"X-Twitter-Active-User":              {"yes"},
//		"X-Twitter-Client-Limit-Ad-Tracking": {"0"},
//	})
//	resp, err := client.SetDebug(s.ProxyDebug).R().SetBody(string(numberFlowTokenData)).
//		Post(fmt.Sprintf("%v", twitterFlowTokenUrl))
//	if err != nil {
//		if s.PrintMore {
//			log.Err(fmt.Sprintf("任务ID:%v 任务批次:%v 请求接口错误:%v", params.TaskInfo.Id, params.BatchIndex, err))
//		}
//		s.dealTokenInvalid(err, tokenData)
//		return roundTripper, false, proxyURL, err
//	}
//
//	var flowResp = &FlowTokenResp{}
//	if err = json.Unmarshal(resp.Body(), flowResp); err != nil {
//		return roundTripper, false, proxyURL, err
//	}
//
//	att := ""
//	attHeader := resp.RawResponse.Header.Values("att")
//	if len(attHeader) > 0 {
//		att = attHeader[0]
//	}
//
//	//初始化含有token 以及请求头att
//	attAndFlowToken.FlowToken = flowResp.FlowToken
//	attAndFlowToken.Status = flowResp.Status
//	attAndFlowToken.Att = att
//
//	return roundTripper, true, proxyURL, nil
// }
//
// func (s *twitterExecutor) step4(phone string, params execute.TaskExecutorParams, roundTripper http.RoundTripper,
//	reuseProxy bool, tokenData *TokenData, flowCh *AttAndFlowTokenResp) (http.RoundTripper, bool, *url.URL, error) {
//
//	var (
//		client        = resty.New()
//		proxyURL      *url.URL
//		guestTokenUrl = "https://api.twitter.com/1.1/onboarding/task.json"
//	)
//	if !reuseProxy {
//		/* 如果不带用代理复用策略，那么就重新获取代理 */
//		roundTripper, proxyURL = execute.SetDefaultTransport("", s.getNetWorkConfig())
//	}
//
//	numberFlowToken := NumberVerifyInfo
//	//获取返回信息
//	numberFlowToken.FlowToken = flowCh.FlowToken
//	numberFlowToken.SubtaskInputs[0].EnterText.Text = phone
//	numberFlowToken.SubtaskInputs[0].EnterText.SuggestionId = nil
//	numberVerifyData, _ := json.Marshal(numberFlowToken)
//	client.SetTransport(roundTripper).SetTimeout(s.getNetWorkConfig().HttpConfig.Timeout)
//
//	step4AddHeader(client.Header, map[string][]string{
//		"OS-Version":                         {"29"},
//		"att":                                {flowCh.Att},
//		"Authorization":                      {tokenData.Authorization},
//		"Cookie":                             {tokenData.Cookie},
//		"Content-Length":                     {strconv.Itoa(len(numberVerifyData))},
//		"Content-Type":                       {"application/json; charset=utf-8"},
//		"System-User-Agent":                  {"Dalvik/2.1.0 (Linux; U; Android 10; Pixel 3 Build/QQ3A.200805.001"},
//		"Twitter-Display-Size":               {"1080x2028x440"},
//		"X-Guest-Token":                      {tokenData.XGuestToken},
//		"X-B3-TraceId":                       {utils.RandomString(16)},
//		"X-Client-UUID":                      {tokenData.XClientUUID},
//		"X-Twitter-Client-AdID":              {tokenData.XTwitterClientAdID},
//		"X-Twitter-Client-AppSetID":          {tokenData.XTwitterClientAppSetID},
//		"X-Twitter-Client-DeviceID":          {tokenData.XTwitterClientDeviceID},
//		"X-Twitter-Active-User":              {"yes"},
//		"X-Twitter-Client-Limit-Ad-Tracking": {"0"},
//	})
//	resp, err := client.SetDebug(s.ProxyDebug).R().SetBody(string(numberVerifyData)).
//		Post(fmt.Sprintf("%v", guestTokenUrl))
//	if err != nil {
//		if s.PrintMore {
//			log.Err(fmt.Sprintf("任务ID:%v 任务批次:%v 请求接口错误:%v", params.TaskInfo.Id, params.BatchIndex, err))
//		}
//		s.dealTokenInvalid(err, tokenData)
//		return roundTripper, false, proxyURL, err
//	}
//
//	respHeader := resp.Header()
//
//	//X-Rate-Limit-Remaining
//	rateLimitRemaining := respHeader.Get("X-Rate-Limit-Remaining")
//	tokenData.XRateLimitRemaining, _ = strconv.Atoi(rateLimitRemaining)
//
//	xRateLimitLimit := respHeader.Get("X-Rate-Limit-Limit")
//	tokenData.XRateLimitLimit, _ = strconv.Atoi(xRateLimitLimit)
//
//	xRateLimitReset := respHeader.Get("X-Rate-Limit-Reset")
//	tokenData.XRateLimitReset, _ = strconv.Atoi(xRateLimitReset)
//
//	b, err := parseResult(resp.Body(), tokenData)
//	return roundTripper, b, proxyURL, err
// }
//
// func parseResult(body []byte, tokenData *TokenData) (bool, error) {
//
//	twitterResp := NumberVerifyResp{}
//	err := json.Unmarshal(body, &twitterResp)
//	if err != nil {
//		return false, execute.RequestErrorNetError
//	}
//
//	if twitterResp.Status == "success" { //success
//		subtaskId := twitterResp.Subtasks[0].SubtaskId
//		//号码存在 || 账号存在（但是提示账号存在异常登录活动）
//		if subtaskId == "LoginEnterPassword" || subtaskId == "LoginEnterAlternateIdentifierSubtask" { //LoginEnterPassword
//			return true, nil
//		}
//		//频率过快，需要切换ip
//		if subtaskId == "DenyLoginSubtask" {
//			return false, execute.RequestErrorRateLimitExceeded
//		}
//	}
//
//	//没有找到账号：
//	//{"errors":[{"code":399,"message":"抱歉，我们无法找到你的账号。"}]}
//	//{"errors":[{"code":399,"message":"Sorry, we could not find your account."}]}
//	if twitterResp.Errors[0].Code == 399 && (strings.Contains(twitterResp.Errors[0].Message, "Sorry, we could not find your account.")) { // Sorry, we could not find your account.
//		return false, nil
//	}
//
//	if twitterResp.Errors[0].Code == 366 && (strings.Contains(twitterResp.Errors[0].Message, "flow token not recognized Invalid flow token")) { // flow token not recognized Invalid flow token
//		tokenData.IsExpiredFlowToken.Set(true)
//		return false, execute.RequestErrorBadFlowToken
//	}
//
//	//Guest_token过期：
//	//{"errors":[{"message":"Bad guest token","code":239}]}
//	if twitterResp.Errors[0].Code == 239 && (strings.Contains(twitterResp.Errors[0].Message, "Bad guest token")) {
//		tokenData.IsBadGuestToken.Set(true)
//		return false, execute.RequestErrorBadGuestToken
//	}
//
//	// 缺少前面获取的参数去请求时
//	// 这个token失效，需要丢弃
//	//{"errors":[{"code":348,"message":"Client application is not permitted to access this api."}]}
//	if twitterResp.Errors[0].Code == 348 && (strings.Contains(twitterResp.Errors[0].Message, "Client application is not permitted to access this api.")) {
//		tokenData.IsTokenInvalid.Set(true)
//		return false, execute.RequestErrorBadToken
//	}
//
//	//flow_token被消费需要重新获取
//	//{"errors":[{"code":366,"message":"flow name LoginFlow is currently not accessible"}]}
//	if twitterResp.Errors[0].Code == 366 && strings.Contains(twitterResp.Errors[0].Message, "flow name LoginFlow is currently not accessible") {
//		tokenData.IsExpiredFlowToken.Set(true)
//		return false, execute.RequestErrorBadFlowToken
//	}
//
//	return false, execute.RequestErrorCanceledError
// }
//
// func (s *twitterExecutor) dealTokenInvalid(err error, tokenData *TokenData) bool {
//	/*
//		remote error: tls: unexpected message  183
//		remote error: tls: protocol version not supported 61
//		remote error: tls: bad record MAC 70
//		tls: server did not echo the legacy session ID  307
//	*/
//	if strings.LastIndex(err.Error(), "tls:") != -1 {
//		tokenData.IsTokenInvalid.Set(true)
//		return true
//	}
//
//	return false
// }
//
// func step4AddHeader(header http.Header, headers map[string][]string) {
//	header.Add("Accept", "application/json")
//	header.Add("Accept-Language", "en-US")
//	header.Add("Accept-Encoding", "br, gzip, deflate")
//	header.Add("Cache-Control", "no-store")
//	header.Add("Host", "api.twitter.com")
//	header.Add("OS-Security-Patch-Level", "2020-08-05")
//	header.Add("Optimize-Body", "true")
//	header.Add("Timezone", "America/New_York")
//	header.Add("User-Agent", "TwitterAndroid/9.75.0-release.0 (29750000-r-0) Pixel+3/10 (Google;Pixel+3;google;blueline;0;;1;2015)")
//
//	header.Add("X-Twitter-Active-User", "no")
//	header.Add("X-Twitter-API-Version", "5")
//	header.Add("X-Twitter-Client", "TwitterAndroid")
//	header.Add("X-Twitter-Client-Language", "en-US")
//	header.Add("X-Twitter-Client-Version", "9.75.0-release.0")
//	header.Add("X-Twitter-Client-Flavor", "")
//
//	//header.Add("Connection", "Keep-Alive")
//	header.Add("Connection", "close")
//	header.Add("Proxy-Connection", "close")
//	//request.Header.Add("Proxy-Authenticate", "auth")
//	//request.Header.Add("Proxy-Authorization", "auth")
//	for k, v := range headers {
//		header[k] = v
//	}
// }
//
// func step3AddHeader(header http.Header, headers map[string][]string) {
//	header.Add("Accept", "application/json")
//	header.Add("Accept-Language", "en-US")
//	header.Add("Accept-Encoding", "br, gzip, deflate")
//	header.Add("Cache-Control", "no-store")
//	header.Add("Host", "api.twitter.com")
//	header.Add("OS-Security-Patch-Level", "2020-08-05")
//	header.Add("Optimize-Body", "true")
//	header.Add("Timezone", "America/New_York")
//	header.Add("User-Agent", "TwitterAndroid/9.75.0-release.0 (29750000-r-0) Pixel+3/10 (Google;Pixel+3;google;blueline;0;;1;2015)")
//
//	header.Add("X-Twitter-Active-User", "no")
//	header.Add("X-Twitter-API-Version", "5")
//	header.Add("X-Twitter-Client", "TwitterAndroid")
//	header.Add("X-Twitter-Client-Language", "en-US")
//	header.Add("X-Twitter-Client-Version", "9.75.0-release.0")
//	header.Add("X-Twitter-Client-Flavor", "")
//
//	//header.Add("Connection", "Keep-Alive")
//	header.Add("Connection", "close")
//	header.Add("Proxy-Connection", "close")
//	//request.Header.Add("Proxy-Authenticate", "auth")
//	//request.Header.Add("Proxy-Authorization", "auth")
//	for k, v := range headers {
//		header[k] = v
//	}
// }
//
// func step2AddHeader(header http.Header, headers map[string][]string) {
//	header.Add("Accept", "application/json")
//	header.Add("Accept-Language", "en-US")
//	header.Add("Accept-Encoding", "br, gzip, deflate")
//	header.Add("Cache-Control", "no-store")
//	header.Add("Host", "api.twitter.com")
//	header.Add("OS-Security-Patch-Level", "2020-08-05")
//	header.Add("Optimize-Body", "true")
//	header.Add("Timezone", "America/New_York")
//	header.Add("User-Agent", "TwitterAndroid/9.75.0-release.0 (29750000-r-0) Pixel+3/10 (Google;Pixel+3;google;blueline;0;;1;2015)")
//
//	header.Add("X-Twitter-Active-User", "no")
//	header.Add("X-Twitter-API-Version", "5")
//	header.Add("X-Twitter-Client", "TwitterAndroid")
//	header.Add("X-Twitter-Client-Language", "en-US")
//	header.Add("X-Twitter-Client-Version", "9.75.0-release.0")
//	header.Add("X-Twitter-Client-Flavor", "")
//
//	//header.Add("Connection", "Keep-Alive")
//	header.Add("Connection", "close")
//	header.Add("Proxy-Connection", "close")
//	//request.Header.Add("Proxy-Authenticate", "auth")
//	//request.Header.Add("Proxy-Authorization", "auth")
//	for k, v := range headers {
//		header[k] = v
//	}
// }
//
// func step1AddHeader(header http.Header, headers map[string][]string) {
//	header.Add("Accept", "application/json")
//	header.Add("Accept-Language", "en-US")
//	header.Add("Accept-Encoding", "br, gzip, deflate")
//	header.Add("Cache-Control", "no-store")
//	header.Add("Host", "api.twitter.com")
//	header.Add("OS-Security-Patch-Level", "2020-08-05")
//	header.Add("Optimize-Body", "true")
//	header.Add("Timezone", "America/New_York")
//	header.Add("User-Agent", "TwitterAndroid/9.75.0-release.0 (29750000-r-0) Pixel+3/10 (Google;Pixel+3;google;blueline;0;;1;2015)")
//
//	header.Add("X-Twitter-Active-User", "no")
//	header.Add("X-Twitter-API-Version", "5")
//	header.Add("X-Twitter-Client", "TwitterAndroid")
//	header.Add("X-Twitter-Client-Language", "en-US")
//	header.Add("X-Twitter-Client-Version", "9.75.0-release.0")
//	header.Add("X-Twitter-Client-Flavor", "")
//
//	//request.Header.Add("Connection", "Keep-Alive")
//	header.Add("Connection", "close")
//	header.Add("Proxy-Connection", "close")
//	//request.Header.Add("Proxy-Authenticate", "auth")
//	//request.Header.Add("Proxy-Authorization", "auth")
//	for k, v := range headers {
//		header[k] = v
//	}
// }
